import logging
from dataclasses import dataclass

from src.application.user import dto
from src.application.user.converters import convert_active_user_entity_to_dto
from src.application.user.exceptions import UserIdAlreadyExist
from src.application.user.uow import UserUoW
from src.domain.user.aggregates import UserAggregate
from src.domain.user.value_objects import TelegramUserId

logger = logging.getLogger(__name__)


@dataclass(frozen=True)
class CreateUser:
    tg_id: int
    username: str


class CreateUserHandler:
    """
    Создание tg пользователя
    """

    def __init__(
        self,
        *,
        uow: UserUoW,
    ) -> None:
        self._uow = uow

    async def __call__(self, command: CreateUser) -> dto.UserDTO:
        user_tg_id = TelegramUserId(value=command.tg_id)
        user = UserAggregate.create_user(
            telegram_id=user_tg_id,
            username=command.username,
        )

        if await self._uow.user_repo.check_user_exists(user_tg_id):
            raise UserIdAlreadyExist(command.tg_id)

        try:
            await self._uow.user_repo.create_user(user)
        except Exception as err:
            await self._uow.rollback()
            raise err

        await self._uow.commit()

        logger.info("User created", extra={"user": user})

        user_dto = convert_active_user_entity_to_dto(user)

        return user_dto
